{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 程序说明\n",
    "时间：2016年11月16日\n",
    "\n",
    "说明：该程序是一个包含两个隐藏层的神经网络，最后会保存模型到h5文件中。\n",
    "\n",
    "数据集：MNIST"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.加载keras模块"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from __future__ import print_function\n",
    "import numpy as np\n",
    "np.random.seed(1337)  # for reproducibility"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "from keras.datasets import mnist\n",
    "from keras.models import Sequential\n",
    "from keras.layers.core import Dense, Dropout, Activation\n",
    "from keras.optimizers import SGD, Adam, RMSprop\n",
    "from keras.utils import np_utils"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.变量初始化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "batch_size = 128 \n",
    "nb_classes = 10\n",
    "nb_epoch = 20 "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.准备数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "60000 train samples\n",
      "10000 test samples\n"
     ]
    }
   ],
   "source": [
    "# the data, shuffled and split between train and test sets\n",
    "(X_train, y_train), (X_test, y_test) = mnist.load_data()\n",
    "\n",
    "X_train = X_train.reshape(60000, 784)\n",
    "X_test = X_test.reshape(10000, 784)\n",
    "X_train = X_train.astype('float32')\n",
    "X_test = X_test.astype('float32')\n",
    "X_train /= 255\n",
    "X_test /= 255\n",
    "print(X_train.shape[0], 'train samples')\n",
    "print(X_test.shape[0], 'test samples')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 转换类标号"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# convert class vectors to binary class matrices\n",
    "Y_train = np_utils.to_categorical(y_train, nb_classes)\n",
    "Y_test = np_utils.to_categorical(y_test, nb_classes)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4.建立模型\n",
    "### 使用Sequential（）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "model = Sequential()\n",
    "model.add(Dense(512, input_shape=(784,)))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Dropout(0.2))\n",
    "model.add(Dense(512))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Dropout(0.2))\n",
    "model.add(Dense(10))\n",
    "model.add(Activation('softmax'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 打印模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "____________________________________________________________________________________________________\n",
      "Layer (type)                     Output Shape          Param #     Connected to                     \n",
      "====================================================================================================\n",
      "dense_1 (Dense)                  (None, 512)           401920      dense_input_1[0][0]              \n",
      "____________________________________________________________________________________________________\n",
      "activation_1 (Activation)        (None, 512)           0           dense_1[0][0]                    \n",
      "____________________________________________________________________________________________________\n",
      "dropout_1 (Dropout)              (None, 512)           0           activation_1[0][0]               \n",
      "____________________________________________________________________________________________________\n",
      "dense_2 (Dense)                  (None, 512)           262656      dropout_1[0][0]                  \n",
      "____________________________________________________________________________________________________\n",
      "activation_2 (Activation)        (None, 512)           0           dense_2[0][0]                    \n",
      "____________________________________________________________________________________________________\n",
      "dropout_2 (Dropout)              (None, 512)           0           activation_2[0][0]               \n",
      "____________________________________________________________________________________________________\n",
      "dense_3 (Dense)                  (None, 10)            5130        dropout_2[0][0]                  \n",
      "____________________________________________________________________________________________________\n",
      "activation_3 (Activation)        (None, 10)            0           dense_3[0][0]                    \n",
      "====================================================================================================\n",
      "Total params: 669706\n",
      "____________________________________________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.summary()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5.训练与评估\n",
    "### 编译模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "model.compile(loss='categorical_crossentropy',\n",
    "              optimizer=RMSprop(),\n",
    "              metrics=['accuracy'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 迭代训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 60000 samples, validate on 10000 samples\n",
      "Epoch 1/20\n",
      "60000/60000 [==============================] - 4s - loss: 0.2451 - acc: 0.9239 - val_loss: 0.1210 - val_acc: 0.9626\n",
      "Epoch 2/20\n",
      "60000/60000 [==============================] - 3s - loss: 0.1032 - acc: 0.9683 - val_loss: 0.0780 - val_acc: 0.9763\n",
      "Epoch 3/20\n",
      "60000/60000 [==============================] - 3s - loss: 0.0755 - acc: 0.9769 - val_loss: 0.0796 - val_acc: 0.9757\n",
      "Epoch 4/20\n",
      "60000/60000 [==============================] - 3s - loss: 0.0612 - acc: 0.9816 - val_loss: 0.0768 - val_acc: 0.9784\n",
      "Epoch 5/20\n",
      "60000/60000 [==============================] - 3s - loss: 0.0510 - acc: 0.9848 - val_loss: 0.0845 - val_acc: 0.9795\n",
      "Epoch 6/20\n",
      "60000/60000 [==============================] - 3s - loss: 0.0445 - acc: 0.9865 - val_loss: 0.0759 - val_acc: 0.9806\n",
      "Epoch 7/20\n",
      "60000/60000 [==============================] - 3s - loss: 0.0402 - acc: 0.9884 - val_loss: 0.0800 - val_acc: 0.9816\n",
      "Epoch 8/20\n",
      "60000/60000 [==============================] - 3s - loss: 0.0351 - acc: 0.9900 - val_loss: 0.0916 - val_acc: 0.9821\n",
      "Epoch 9/20\n",
      "60000/60000 [==============================] - 3s - loss: 0.0314 - acc: 0.9905 - val_loss: 0.0930 - val_acc: 0.9807\n",
      "Epoch 10/20\n",
      "60000/60000 [==============================] - 3s - loss: 0.0285 - acc: 0.9920 - val_loss: 0.0916 - val_acc: 0.9835\n",
      "Epoch 11/20\n",
      "60000/60000 [==============================] - 3s - loss: 0.0279 - acc: 0.9918 - val_loss: 0.0853 - val_acc: 0.9820\n",
      "Epoch 12/20\n",
      "60000/60000 [==============================] - 3s - loss: 0.0238 - acc: 0.9930 - val_loss: 0.0997 - val_acc: 0.9811\n",
      "Epoch 13/20\n",
      "60000/60000 [==============================] - 3s - loss: 0.0242 - acc: 0.9938 - val_loss: 0.1083 - val_acc: 0.9796\n",
      "Epoch 14/20\n",
      "60000/60000 [==============================] - 3s - loss: 0.0229 - acc: 0.9934 - val_loss: 0.1037 - val_acc: 0.9832\n",
      "Epoch 15/20\n",
      "60000/60000 [==============================] - 3s - loss: 0.0202 - acc: 0.9944 - val_loss: 0.1019 - val_acc: 0.9831\n",
      "Epoch 16/20\n",
      "60000/60000 [==============================] - 3s - loss: 0.0216 - acc: 0.9939 - val_loss: 0.1071 - val_acc: 0.9810\n",
      "Epoch 17/20\n",
      "60000/60000 [==============================] - 3s - loss: 0.0205 - acc: 0.9947 - val_loss: 0.1085 - val_acc: 0.9835\n",
      "Epoch 18/20\n",
      "60000/60000 [==============================] - 3s - loss: 0.0182 - acc: 0.9950 - val_loss: 0.1245 - val_acc: 0.9807\n",
      "Epoch 19/20\n",
      "60000/60000 [==============================] - 3s - loss: 0.0172 - acc: 0.9952 - val_loss: 0.1264 - val_acc: 0.9837\n",
      "Epoch 20/20\n",
      "60000/60000 [==============================] - 3s - loss: 0.0187 - acc: 0.9954 - val_loss: 0.1132 - val_acc: 0.9831\n"
     ]
    }
   ],
   "source": [
    "history = model.fit(X_train, Y_train,\n",
    "                    batch_size=batch_size, nb_epoch=nb_epoch,\n",
    "                    verbose=1, validation_data=(X_test, Y_test))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 模型评估"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test score: 0.113199677604\n",
      "Test accuracy: 0.9831\n"
     ]
    }
   ],
   "source": [
    "score = model.evaluate(X_test, Y_test, verbose=0)\n",
    "print('Test score:', score[0])\n",
    "print('Test accuracy:', score[1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "## 5.模型保存"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "model.save('mnist-mpl.h5')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这个时候你的文件夹下就有一个名字为“mnist-mpl.h5”的模型文件了。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.12"
  },
  "ssap_exp_config": {
   "error_alert": "Error Occurs!",
   "initial": [],
   "max_iteration": 1000,
   "recv_id": "",
   "running": [],
   "summary": [],
   "version": "1.1.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
